package com.gitlab.lucky.weixin.pay;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.gitlab.lucky.common.redis.RedisService;
import com.gitlab.lucky.common.result.R;
import com.gitlab.lucky.common.utils.IpUtils;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

/** Native 支付下单为例 */
@RestController
@RequestMapping("pay")
@Slf4j
public class WxPayController {
    @Value("${wx.domain}")
    private String domain;
    @Autowired
    private WxPayService wxPayService;
    @Autowired
    private WxMpService wxMpService;
    @Autowired
    private RedisService redisService;
    @RequestMapping(value = "wxpay")
    public R wxPay(String openId,HttpServletRequest request) {
        String orderNum = IdUtil.getSnowflakeNextIdStr();
        String ip = IpUtils.getIpAddr(request);
        String notifyUrl = domain+"/pay/payNotify";
        try {
            WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
            orderRequest.setBody("账号下单支付");
            orderRequest.setNotifyUrl(notifyUrl);
            orderRequest.setOutTradeNo(orderNum);
            Object amount = redisService.get("amount");
            Object o = ObjectUtil.isNull(amount) ? 540 : amount;
            int i = Integer.parseInt(o.toString());
            orderRequest.setTotalFee(i);
            orderRequest.setOpenid(openId);
            orderRequest.setSpbillCreateIp(ip);
            WxPayMpOrderResult order = wxPayService.createOrder(orderRequest);
            return R.ok().data(order);
        } catch (Exception e) {
            log.error("微信支付失败！OPENID:{},订单号:{},IP:[{}],原因:{}",openId,orderNum,ip,e.getMessage());
            return R.error("微信支付失败，请稍后重试！");
        }
    }
    @RequestMapping("/payNotify")
    public String payNotify(HttpServletRequest request) {
        try {
            String xmlResult = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
            WxPayOrderNotifyResult result = wxPayService.parseOrderNotifyResult(xmlResult);
            // 加入自己处理订单的业务逻辑，需要判断订单是否已经支付过，否则可能会重复调用
            String openid = result.getOpenid();
            String orderId = result.getOutTradeNo();
            log.info("支付回调通知,OPEN_ID:[{}],ORDER_ID:[{}]",openid,orderId);
            Object flag = redisService.get("pay_" + orderId);
            if (ObjectUtil.isNull(flag)) {
                redisService.set("pay_" + orderId, orderId,30*5);
                Object phone = redisService.pop("TELD_PHONE");
                if (ObjectUtil.isNull(phone)) {
                    log.error("库存不足，请及时补充，客户openid为:" + openid);
                    redisService.push("SUPPLEMENT",openid);
                    //退款
                    //refund(result);
                    return WxPayNotifyResponse.success("库存不足");
                }
                String msg = "用户名:%s\r\n密码:abc123123";
                //发送客服消息
                WxMpKefuMessage build = WxMpKefuMessage
                        .TEXT()
                        .toUser(openid)
                        .content(String.format(msg, phone))
                        .build();
                wxMpService.getKefuService().sendKefuMessage(build);
                return WxPayNotifyResponse.success("处理成功!");
            }
            return WxPayNotifyResponse.success("重复回调用");
        } catch (Exception e) {
            log.error("微信回调结果异常,异常原因{}", e.getMessage());
            return WxPayNotifyResponse.fail(e.getMessage());
        }
    }
    private WxPayRefundResult refund(WxPayOrderNotifyResult result) throws WxPayException {
        WxPayRefundRequest wxPayRefundRequest = new WxPayRefundRequest();
        wxPayRefundRequest.setOutTradeNo(result.getOutTradeNo());
        wxPayRefundRequest.setRefundFee(result.getTotalFee());
        wxPayRefundRequest.setTotalFee(result.getTotalFee());
        String outRefundNo = IdUtil.getSnowflakeNextIdStr();
        wxPayRefundRequest.setOutRefundNo(outRefundNo);
        WxPayRefundResult refund = wxPayService.refund(wxPayRefundRequest);
        log.info("退款信息:[{}]", JSONUtil.toJsonStr(refund));
        return refund;
    }
    @RequestMapping("pushPhone")
    public R pushPhone(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            return R.error("请选择要上传的文件");
        }
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(file.getInputStream()))) {
            String line;
            List<String> phoneList = new ArrayList<>();
            while (StrUtil.isNotBlank((line = reader.readLine()))) {
                // 在这里处理每一行的文本内容
                phoneList.add(line);
            }
            redisService.lpush("TELD_PHONE",phoneList);
            return R.ok().data(phoneList.size());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return R.error();
    }
}
